package com.boot.security;

import com.boot.dao.IUserDao;
import com.boot.domian.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Chunsheng.Zhang
 * @date 2021/1/26 16:45
 * @description : TODO
 */

@Slf4j
@Configuration
@EnableWebSecurity  //启用springsecurity安全验证
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    //1 定义用户信息服务(基于内存的方式)
    @Bean
    @Override
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("zs").password("123").authorities("m1").build());
        manager.createUser(User.withUsername("ls").password("456").authorities("m2").build());
        return manager;
    }

    //1 定义用户信息服务(基于查询数据库方式)
//    @Bean
//    @Override
//    public UserDetailsService userDetailsService() {    //用户登录实现
//        return new UserDetailsService() {
//            @Autowired
//            private IUserDao userDao;
//
//            @Override
//            public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
//                SysUser user = userDao.findByUsername(s);
//                if (user == null) throw new UsernameNotFoundException("Username " + s + " not found");
//                return new SecurityUser(user);
//            }
//        };
//    }





    //2 定义密码编码器

    /**
     *
     * 有很多密码对比的形式，md5，等等
     *
     * 此处采用的是直接进行字符串比较
     *
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }





    //3 配置安全拦截机制
    @Override
    protected void configure(HttpSecurity http) throws Exception { //配置策略

        http.authorizeRequests()
                .antMatchers("/user/m1").hasAuthority("m1") //要求访问  /user/m1  的主体必须拥有m1 权限
                .antMatchers("/user/m2").hasAuthority("m2")
                .antMatchers("/user/**").authenticated()  //所有的对  /user/**  请求必须认证通过
                .anyRequest().permitAll()  //其他的请求，可以直接通过
                .and()
                .formLogin()  //允许表单登录
                .successForwardUrl("/login-success");  //自定义登录成功之后的跳转路径


//        http.csrf().disable()   //关闭csrf
//                .authorizeRequests()
//                .antMatchers("/static/**").permitAll().anyRequest().authenticated()  //对于对 /static/**  请求都放行，其他的请求必须认证通过
//                .and()
//                .formLogin().loginPage("/login").permitAll().successHandler(loginSuccessHandler())
//                .and()
//                .logout().permitAll().invalidateHttpSession(true).deleteCookies("JSESSIONID").logoutSuccessHandler(logoutSuccessHandler())
//                .and()
//                .rememberMe()
//                .and().sessionManagement().maximumSessions(10).expiredUrl("/login");
    }






//    @Autowired
//    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
//        auth.eraseCredentials(false);
//    }

//    @Bean
//    public TokenBasedRememberMeServices tokenBasedRememberMeServices() {
//        return new TokenBasedRememberMeServices("springRocks", userDetailsService());
//    }




//    @Bean
//    public LogoutSuccessHandler logoutSuccessHandler() { //登出处理
//        return (httpServletRequest, httpServletResponse, authentication) -> {
//            try {
//                SecurityUser user = (SecurityUser) authentication.getPrincipal();
//                log.info("USER : {} LOGOUT SUCCESS ! ", user.getUsername());
//            } catch (Exception e) {
//                log.error("printStackTrace", e);
//            }
//            httpServletResponse.sendRedirect("/login");
//        };
//    }

//    @Bean
//    public SavedRequestAwareAuthenticationSuccessHandler loginSuccessHandler() { //登入处理
//        return new SavedRequestAwareAuthenticationSuccessHandler() {
//            @Override
//            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//                SysUser userDetails = (SysUser) authentication.getPrincipal();
//                log.info("USER : {} LOGIN SUCCESS !  ", userDetails.getUsername());
//                super.onAuthenticationSuccess(request, response, authentication);
//            }
//        };
//    }




}
